﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Configuration;

namespace AgileFx.MVC.PerformanceTools
{
    //This will blow up if we use multiple threads to handle a request. 
    //  (Eg Asp.Net Async Pages, other ThreadPool threads etc)
    //However, this should suffice for the way things work by default.
    public class PerformanceSpy : IHttpModule
    {
        public String ModuleName
        {
            get { return "Performance Spy Module"; }
        }

        [ThreadStatic]
        private static TraceContext _TraceContext;
        public static TraceContext TraceContext
        {
            get
            {
                //_TraceContext will be null only for parallel execution
                if (_TraceContext == null)
                    _TraceContext = new TraceContext();
                return _TraceContext;
            }
            set
            {
                _TraceContext = value;
            }
        }
        public static string[] OmittedExtensions;
        public static string[] LogStackFramesFromNamespaces;
        public static string[] ExcludeStackFramesFromNamespaces;

        #region IHttpModule Members

        public void Dispose()
        {
            //throw new NotImplementedException();
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += (new EventHandler(this.Application_BeginRequest));
            context.EndRequest += (new EventHandler(this.Application_EndRequest));
            LogWriter.ConnectionString = ConfigurationSettings.AppSettings["PerformanceSpy_ConnectionString"];
            OmittedExtensions = ConfigurationSettings.AppSettings["PerformanceSpy_OmitExtensions"].Split(',').ToArray();
            LogStackFramesFromNamespaces = ConfigurationSettings.AppSettings["PerformanceSpy_LogStackFramesFromNamespaces"].Split(',').ToArray();
            ExcludeStackFramesFromNamespaces = ConfigurationSettings.AppSettings["PerformanceSpy_ExcludeStackFramesFromNamespaces"].Split(',').ToArray();
        }

        #endregion

        private void Application_BeginRequest(Object source,
         EventArgs e)
        {
            TraceContext = new TraceContext();
            
            var httpContext = HttpContext.Current;
            var url = httpContext.Request.Url.ToString();
            
            if (!OmittedExtensions.Any(ext => url.EndsWith(ext)))
                TraceContext.WriteToLog("BeginRequest", url);
        }

        private void Application_EndRequest(Object source, EventArgs e)
        {
            var httpContext = HttpContext.Current;

            var url = httpContext.Request.Url.ToString();

            if (!OmittedExtensions.Any(ext => url.EndsWith(ext)))
                TraceContext.WriteToLog("EndRequest", url);
        }
    }
}
